/*
 * @Author: cooper
 * @Date: 2025-03-30 21:35:19
 * @Wechat: cmd_develop
 * @Description: 机械臂驱动
 */
#include "./bsp_lift.h"

lift_buffer lift_Buffer;

SemaphoreHandle_t lift_finish_sem = 0; // 信号量

QueueHandle_t lift_basic_work_queue = 0; // lift工作邮箱

// MKS接收数据处理任务句柄
TaskHandle_t lift_work_task_handler;

/// @brief lift串口DMA接受
/// @param
void LIFT_UART_DMA_RX(void)
{
    dma_init_type dma_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    /* 使能dma复用功能 */
    dmamux_enable(DMA1, TRUE);
    /* 复位指定的 DMA 通道 */
    dma_reset(DMA1_CHANNEL6);
    /* 默认填充配置 */
    dma_default_para_init(&dma_init_struct);
    /* DMA 传输数据量+传输方向 */
    dma_init_struct.buffer_size = LIFT_DATA_SIZE;
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
    /* 外设地址+数据宽度+地址增加模式 */
    dma_init_struct.peripheral_base_addr = (uint32_t)&USART6->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    /* 存储器地址+数据宽度+地址增加模式 */
    dma_init_struct.memory_base_addr = (uint32_t)(&(RX_LIFT(0)));
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    /* 优先级+循环模式 */
    dma_init_struct.priority = DMA_PRIORITY_LOW;
    dma_init_struct.loop_mode_enable = FALSE;
    /* 初始化指定的 DMA 通道 */
    dma_init(DMA1_CHANNEL6, &dma_init_struct);
    /* 初始化dma复用功能 */
    dmamux_init(DMA1MUX_CHANNEL6, DMAMUX_DMAREQ_ID_USART6_RX);
    /* 使能指定通道 */
    dma_channel_enable(DMA1_CHANNEL6, TRUE);
    /* 清除数据接收 */
    RX_LIFT_BufClear();
}

/**
 * @brief  lift串口DMA发送
 * @param  none
 * @retval none
 */
void LIFT_UART_DMA_TX(u16 size)
{
    dma_init_type dma_init_struct;
    /* 使能时钟 */
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    /* 使能dma复用功能 */
    dmamux_enable(DMA1, TRUE);
    /* 复位指定的 DMA 通道 */
    dma_reset(DMA1_CHANNEL6);
    /* 默认填充配置 */
    dma_default_para_init(&dma_init_struct);
    /* DMA 传输数据量+传输方向 */
    dma_init_struct.buffer_size = size;
    dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
    /* 存储器地址+数据宽度+地址增加模式 */
    dma_init_struct.memory_base_addr = (uint32_t)(&(TX_LIFT(0)));
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    /* 外设地址+数据宽度+地址增加模式 */
    dma_init_struct.peripheral_base_addr = (uint32_t)&USART6->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    /* 优先级+循环模式 */
    dma_init_struct.priority = DMA_PRIORITY_LOW;
    dma_init_struct.loop_mode_enable = FALSE;
    /* 使能DMA发送完成中断 */
    dma_interrupt_enable(DMA1_CHANNEL6, DMA_FDT_INT, TRUE);
    nvic_irq_enable(DMA1_Channel6_IRQn, 2, 2);
    /* 初始化指定的 DMA 通道 */
    dma_init(DMA1_CHANNEL6, &dma_init_struct);
    /* 初始化dma复用功能 */
    dmamux_init(DMA1MUX_CHANNEL6, DMAMUX_DMAREQ_ID_USART6_TX);
    /* 使能指定通道 */
    dma_channel_enable(DMA1_CHANNEL6, TRUE);
}

/**
 * @brief  4号RS485——lift初始化
 * @param  none
 * @retval none
 */
void LIFT_UART_INIT(void)
{
    gpio_init_type gpio_init_struct;

    /* 使能时钟 */
    crm_periph_clock_enable(CRM_USART6_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);

    /* GPIO配置 */
    gpio_default_para_init(&gpio_init_struct);
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins = GPIO_PINS_6 | GPIO_PINS_7;
    gpio_init(GPIOC, &gpio_init_struct);

    /* 复用 */
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE6, GPIO_MUX_8);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE7, GPIO_MUX_8);

    /* 串口参数 */
    usart_reset(USART6);
    usart_init(USART6, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
    usart_transmitter_enable(USART6, TRUE);
    usart_receiver_enable(USART6, TRUE);
    /* 中断配置 */
    nvic_irq_enable(USART6_IRQn, 2, 2);
    usart_interrupt_enable(USART6, USART_IDLE_INT, TRUE);
    /* 使用DMA */
    usart_dma_receiver_enable(USART6, TRUE);
    usart_dma_transmitter_enable(USART6, TRUE);
    /* 使能 */
    usart_enable(USART6, TRUE);
    /* DMA接收	*/
    LIFT_UART_DMA_RX();
}

/**
 * @brief  lift串口3中断处理函数
 * @param  none
 * @retval none
 */
void USART6_IRQHandler(void)
{
    uint32_t ulReturn;
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    /* 进入临界段，临界段可以嵌套 */
    ulReturn = taskENTER_CRITICAL_FROM_ISR();
    if (usart_flag_get(USART6, USART_IDLEF_FLAG) != RESET)
    {
        dma_channel_enable(DMA1_CHANNEL6, FALSE);
        dma_flag_clear(DMA1_FDT6_FLAG);
        // 获取接收总数
        RX_LIFT_TOTAL = LIFT_DATA_SIZE - dma_data_number_get(DMA1_CHANNEL6);
        // 切换任务
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
        usart_flag_clear(USART6, USART_IDLEF_FLAG);
    }
    /* 推出临界段 */
    taskEXIT_CRITICAL_FROM_ISR(ulReturn);
}

/**
 * @brief  lift串口DMA1通道1中断处理函数
 * @param  none
 * @retval none
 */
void DMA1_Channel6_IRQHandler(void)
{
    uint32_t ulReturn;
    /* 进入临界段，临界段可以嵌套 */
    ulReturn = taskENTER_CRITICAL_FROM_ISR();
    if (dma_interrupt_flag_get(DMA1_FDT6_FLAG))
    {
        // DMA接收
        LIFT_UART_DMA_RX();
        dma_flag_clear(DMA1_FDT6_FLAG);
    }
    /* 退出临界段 */
    taskEXIT_CRITICAL_FROM_ISR(ulReturn);
}

void lift_work_task_function(void *parameter)
{
    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(300));
    }
}

void LIFT_TASK(void)
{
    // 串口初始化
    LIFT_UART_INIT();

    // 创建长轴工作任务
    xTaskCreate((TaskFunction_t)lift_work_task_function,
                (const char *)"LIFT_WORK_TASK",
                (uint16_t)configMINIMAL_STACK_SIZE, // 128
                (void *)NULL,
                (UBaseType_t)3,
                (TaskHandle_t *)&lift_work_task_handler);
}
